package com.tenoz.display3d
{
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	public class CurvingRoadTest3 extends Sprite
	{
		protected var bgd:BitmapData;
		
		protected var road:ByteArray = new ByteArray();
		protected var visibleRoad:Array = new Array();
		
		protected var dir:Point = new Point();
		protected var deltaDir:Point = new Point();
		protected var matrix:Matrix = new Matrix();
		protected var position:int = 0;
		
		protected const STEP_LENGTH:int = 40;
		protected const SEGMENTS:int = 50;
		protected const ROAD_WIDTH:int = 100;
		
		public function get pos():int 
		{
			return position;
		}
		public function set pos(value:int):void
		{
			position = value;
			
			var i:int = (position/STEP_LENGTH) << 2;
			if(i < road.length)
			{
				if(i > 0)
				{
					road.position = i;
				}
				else
				{
					road.position = road.length + i%road.length;
				}
			}
			else road.position = i%road.length;
			
			for( i=0; i<SEGMENTS; i++) 
			{
				if(road.position == road.length)
				{
					road.position = 0;
				}
				
				visibleRoad[i] = road.readInt();
			}
			
			draw();
		}
		public function resetPos():void
		{
			var i:int = (position/STEP_LENGTH) << 2;
			if(i > road.length || i < 0)
			{
				i = i%road.length;
				position = position%STEP_LENGTH + i;
			}
		}
		
		public function CurvingRoadTest3(_bgd:BitmapData)
		{
			this.bgd = _bgd;
			
			var degrees:int = 0;
			var i:int
			var delta:int
			road.writeInt(degrees);
			
			i = 50;
			delta = 0;
			for( ; i>0; i--)
			{
				degrees += delta;
				road.writeInt(degrees);
			}
			for(var j:int=0; j<20; j++)
			{
				i = 60;
				delta = Math.random()*6-3;
				for( ; i>0; i--)
				{
					degrees += delta;
					road.writeInt(degrees);
				}
			}
			i = degrees%360;
			delta = -1;
			for( ; i>0; i--)
			{
				degrees += delta;
				road.writeInt(degrees);
			}
			
			this.pos = 0;
		}
		
		protected function draw():void
		{
			dir.x = dir.y = 0;
			var _z:Number = 0;
			var first:int = visibleRoad[0];
			var next:int = 0;
			var i:int=1;
			var offY:int = position%STEP_LENGTH;
			var perc:Number = offY/STEP_LENGTH;
			
			var g:Graphics = this.graphics;
			g.clear();
			g.lineStyle(1,0);
			
			var pp1:Point;
			var pp2:Point;
			
			var pp3:Point = new Point(ROAD_WIDTH,0);
			var pp4:Point = new Point(-ROAD_WIDTH,0);
			
			var angle:Number = (visibleRoad[1]-first)*perc;
			
			for( ; i<SEGMENTS; i++)
			{
				next = visibleRoad[i];
				deltaDir.x = Math.sin(Math.PI*(first-next+angle)/180);
				deltaDir.y = Math.cos(Math.PI*(first-next+angle)/180);
				dir.x += deltaDir.x*STEP_LENGTH;
				dir.y += deltaDir.y*STEP_LENGTH;
				
				pp1 = projection(dir.x-ROAD_WIDTH*deltaDir.y, (dir.y - offY)+ROAD_WIDTH*deltaDir.x, 10);
				pp2 = projection(dir.x+ROAD_WIDTH*deltaDir.y, (dir.y - offY)-ROAD_WIDTH*deltaDir.x, 10);
				
//				matrix.a = matrix.d = deltaDir.y * (Point.distance(pp1, pp4)/STEP_LENGTH);
//				matrix.b = deltaDir.x;
//				matrix.c = -deltaDir.x;
				
				if(((road.position>>2)+i)&1)
				{
					g.beginFill(0x404040,1);
				}
				else
				{
					g.beginFill(0x3a3a3a,1);
				}
				g.moveTo(500+pp1.x, 1000-pp1.y);
				g.lineTo(500+pp2.x, 1000-pp2.y);
				g.lineTo(500+pp3.x, 1000-pp3.y);
				g.lineTo(500+pp4.x, 1000-pp4.y);
				g.lineTo(500+pp1.x, 1000-pp1.y);
				
				pp3 = pp2;
				pp4 = pp1;
			}
			
		}
		
		private var FOV:Number = 120;
		protected function projection(_x:Number, _y:Number, rot:Number):Point
		{
			var xO:Number = Math.PI*rot/180;
			var dx:Number = _x;
			var dy:Number = Math.cos(xO)*_y;
			var dz:Number = Math.sin(xO)*_y+FOV;
			
			return new Point(dx*FOV/dz, dy*FOV/dz);
		}
	}
}


